using JT808Protocol.Models.BodyParserStrategy;
using JT808Protocol.Models.BodyParserStrategy.CommonResponse;
using JT808Protocol.Models.BodyParserStrategy.Control;
using JT808Protocol.Models.BodyParserStrategy.DeviceParams;
using JT808Protocol.Models.Enums;
using System;

namespace JT808Protocol.Models
{
    /// <summary>
    /// JT808报文构造器
    /// </summary>
    public class JT808PackageBuilder
    {
        /// <summary>
        /// 平台通用应答
        /// </summary>
        public static class PlatFormCommon
        {
            /// <summary>
            /// 创建响应
            /// </summary>
            /// <param name="requestPackage"></param>
            /// <returns></returns>
            public static JT808Package Build(JT808Package requestPackage, EnumResult result = EnumResult.成功)
            {
                JT808Package package = new JT808Package();
                package.Header = new JT808Header
                {
                    ProtocolVersion = requestPackage.Header.ProtocolVersion,
                    MessageID = (ushort)EnumMessageType.平台通用应答,
                    SimNumber = requestPackage.Header.SimNumber,
                    SerialNumber = (ushort)(requestPackage.Header.SerialNumber + 1)
                };
                package.Body = new DpPlatform_0x8001
                {
                    SerialNum = (ushort)(requestPackage.Header.SerialNumber + 1), //对应的终端消息的流水号,根据请求包流水号加1
                    ID = requestPackage.Header.MessageID,  //对应的终端消息的 ID
                    Result = result //结果
                };

                return package;
            }
        }

        /// <summary>
        /// 终端查询
        /// </summary>
        public static class DeviceQuery
        {
            /// <summary>
            /// 位置信息查询
            /// </summary>
            /// <param name="simNumber">sim卡号</param>
            /// <param name="reqSerialNum">请求包流水号</param>
            /// <param name="version">版本号</param>
            /// <returns>JT808数据包</returns>
            public static JT808Package QueryLocation(string simNumber, ushort reqSerialNum, JT808ProtocolVersion version = JT808ProtocolVersion.v2013)
            {
                JT808Package packageQL = new JT808Package();
                packageQL.Header = new JT808Header
                {
                    ProtocolVersion = version,
                    MessageID = (ushort)EnumMessageType.位置信息查询,
                    SimNumber = simNumber,
                    SerialNumber = (ushort)(reqSerialNum + 1)
                };
                //没有body
                return packageQL;
            }

            /// <summary>
            /// 查询终端参数
            /// </summary>
            /// <param name="simNumber">sim卡号</param>
            /// <param name="reqSerialNum">请求包流水号</param>
            /// <param name="version">版本号</param>
            /// <returns>JT808数据包</returns>
            public static JT808Package QueryParams(string simNumber, ushort reqSerialNum, JT808ProtocolVersion version = JT808ProtocolVersion.v2013)
            {
                JT808Package packageQL = new JT808Package();
                packageQL.Header = new JT808Header
                {
                    ProtocolVersion = version,
                    MessageID = (ushort)EnumMessageType.查询终端参数,
                    SimNumber = simNumber,
                    SerialNumber = (ushort)(reqSerialNum + 1)
                };
                //没有body
                return packageQL;
            }
        }

        /// <summary>
        /// 终端控制
        /// </summary>
        public static class DeviceControl
        {
            /// <summary>
            /// 终端参数设置
            /// </summary>
            /// <param name="deviceParamType">终端参数类型</param>
            /// <param name="text">设置文本</param>
            /// <param name="simNumber">sim卡号</param>
            /// <param name="reqSerialNum">请求包流水号</param>
            /// <param name="version">版本号</param>
            /// <returns>JT808数据包</returns>
            /// <exception cref="Exception"></exception>
            public static JT808Package SetParam(EnumDeviceParamType deviceParamType, string text, string simNumber, ushort reqSerialNum, JT808ProtocolVersion version = JT808ProtocolVersion.v2013)
            {
                var description = EnumDeviceParamTypeHelper.GetDescription(deviceParamType);
                if (description != null)
                {
                    try
                    {
                        IDeviceParam param = null;
                        switch (description.DataType)
                        {
                            case "WORD":
                                ushort word = Convert.ToUInt16(text);
                                param = new DpWordUshort(word);
                                break;

                            case "DWORD":
                                uint dword = Convert.ToUInt32(text);
                                param = new DpDwordUint(dword);
                                break;

                            case "STRING":
                                param = new DpString(text);
                                break;

                            case "BYTE":
                                param = new DpByte(Convert.ToByte(text));
                                break;

                            case "BYTE[]": break;
                            default: return null;
                        }

                        JT808Package packageSP = new JT808Package();
                        packageSP.Header = new JT808Header
                        {
                            ProtocolVersion = version,
                            MessageID = (ushort)EnumMessageType.设置终端参数,
                            SimNumber = simNumber,
                            SerialNumber = (ushort)(reqSerialNum + 1)
                        };
                        PrDeviceParamSet_0x8103 body = new PrDeviceParamSet_0x8103();
                        body.AddParam(param);

                        packageSP.Body = body;

                        return packageSP;
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("终端参数设置错误:数据类型转换失败");
                    }
                }
                else
                    throw new Exception("终端参数设置错误:数据类型未知 ");
            }

            /// <summary>
            /// 文本信息发送终端
            /// </summary>
            /// <param name="text">文本信息</param>
            /// <param name="simNumber">sim卡号</param>
            /// <param name="reqSerialNum">请求包流水号</param>
            /// <param name="version">版本号</param>
            /// <returns>JT808数据包</returns>
            public static JT808Package SendText(EnumTextSendFlag flag, string text, string simNumber, ushort reqSerialNum, JT808ProtocolVersion version = JT808ProtocolVersion.v2013)
            {
                return SendText(text, simNumber, reqSerialNum, flag, version);
            }

            /// <summary>
            /// 终端关机
            /// </summary>
            /// <param name="simNumber">sim卡号</param>
            /// <param name="reqSerialNum">请求包流水号</param>
            /// <param name="version">版本号</param>
            /// <returns>JT808数据包</returns>
            public static JT808Package Shutdown(string simNumber, ushort reqSerialNum, JT808ProtocolVersion version = JT808ProtocolVersion.v2013)
            {
                return BuildDeviceControl(simNumber, reqSerialNum, EnumDeviceControlCommand.终端关机, version);
            }

            /// <summary>
            /// 终端复位
            /// </summary>
            /// <param name="simNumber">sim卡号</param>
            /// <param name="reqSerialNum">请求包流水号</param>
            /// <param name="version">版本号</param>
            /// <returns>JT808数据包</returns>
            public static JT808Package Reset(string simNumber, ushort reqSerialNum, JT808ProtocolVersion version = JT808ProtocolVersion.v2013)
            {
                return BuildDeviceControl(simNumber, reqSerialNum, EnumDeviceControlCommand.终端复位, version);
            }

            /// <summary>
            /// 终端恢复出厂设置
            /// </summary>
            /// <param name="simNumber">sim卡号</param>
            /// <param name="reqSerialNum">请求包流水号</param>
            /// <param name="version">版本号</param>
            /// <returns>JT808数据包</returns>
            public static JT808Package ResetToFactorySetting(string simNumber, ushort reqSerialNum, JT808ProtocolVersion version = JT808ProtocolVersion.v2013)
            {
                return BuildDeviceControl(simNumber, reqSerialNum, EnumDeviceControlCommand.终端恢复出厂设置, version);
            }

            /// <summary>
            /// 关闭数据通信
            /// </summary>
            /// <param name="simNumber">sim卡号</param>
            /// <param name="reqSerialNum">请求包流水号</param>
            /// <param name="version">版本号</param>
            /// <returns>JT808数据包</returns>
            public static JT808Package TurnOffCommunication(string simNumber, ushort reqSerialNum, JT808ProtocolVersion version = JT808ProtocolVersion.v2013)
            {
                return BuildDeviceControl(simNumber, reqSerialNum, EnumDeviceControlCommand.关闭数据通信, version);
            }

            /// <summary>
            /// 关闭所有无线通信
            /// </summary>
            /// <param name="simNumber">sim卡号</param>
            /// <param name="reqSerialNum">请求包流水号</param>
            /// <param name="version">版本号</param>
            /// <returns>JT808数据包</returns>
            public static JT808Package TurnOffAllWirelessCommunication(string simNumber, ushort reqSerialNum, JT808ProtocolVersion version = JT808ProtocolVersion.v2013)
            {
                return BuildDeviceControl(simNumber, reqSerialNum, EnumDeviceControlCommand.关闭所有无线通信, version);
            }

            /// <summary>
            /// 无线升级
            /// </summary>
            /// <param name="simNumber">sim卡号</param>
            /// <param name="reqSerialNum">请求包流水号</param>
            /// <param name="param">终端命令参数</param>
            /// <param name="version">版本号</param>
            /// <returns>JT808数据包</returns>
            public static JT808Package WirelessUpgrade(string param, string simNumber, ushort reqSerialNum, JT808ProtocolVersion version = JT808ProtocolVersion.v2013)
            {
                return BuildDeviceControl(simNumber, reqSerialNum, EnumDeviceControlCommand.无线升级, version, param);
            }

            /// <summary>
            /// 控制终端连接指定服务器
            /// </summary>
            /// <param name="simNumber">sim卡号</param>
            /// <param name="reqSerialNum">请求包流水号</param>
            /// <param name="param">终端命令参数</param>
            /// <param name="version">版本号</param>
            /// <returns>JT808数据包</returns>
            public static JT808Package ConnectServer(string param, string simNumber, ushort reqSerialNum, JT808ProtocolVersion version = JT808ProtocolVersion.v2013)
            {
                return BuildDeviceControl(simNumber, reqSerialNum, EnumDeviceControlCommand.控制终端连接指定服务器, version, param);
            }

            private static JT808Package BuildDeviceControl(string simNumber, int reqSerialNum, EnumDeviceControlCommand command, JT808ProtocolVersion version, string param = "")
            {
                JT808Package packageDC = new JT808Package();
                packageDC.Header = new JT808Header
                {
                    ProtocolVersion = version,
                    MessageID = (ushort)EnumMessageType.终端控制,
                    SimNumber = simNumber,
                    SerialNumber = (ushort)(reqSerialNum + 1)
                };
                packageDC.Body = new PrControl_0x8105
                {
                    CommandWord = command,
                    Parameter = param
                };
                return packageDC;
            }

            private static JT808Package SendText(string text, string simNumber, ushort reqSerialNum, EnumTextSendFlag flag, JT808ProtocolVersion version)
            {
                JT808Package packageTTS = new JT808Package();
                packageTTS.Header = new JT808Header
                {
                    ProtocolVersion = version,
                    MessageID = (ushort)EnumMessageType.文本信息下发,
                    SimNumber = simNumber,
                    SerialNumber = (ushort)(reqSerialNum + 1)
                };
                packageTTS.Body = new PrTextSend_0x8300
                {
                    Flag = flag,
                    Text = text
                };

                return packageTTS;
            }
        }
    }
}